#include "number.h"

long digs;
VALUE rb_cNumber;

VALUE rb_NilClass_to_number (VALUE nil)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_nan();
    
    return result;
}

VALUE rb_String_to_number (VALUE str)
{
    VALUE complex_regex = rb_reg_new_str(rb_enc_str_new("^(.*[^\\s]+)\\s*\\+\\s*(.*)i$", strlen("^(.*[^\\s]+)\\s*\\+\\s*(.*)i$"), rb_utf8_encoding()), 0);
    VALUE complex_match = rb_funcall(complex_regex, rb_intern("match"), 1, str);
    
    if (RTEST(complex_match))
    {
        VALUE complex_captures = rb_funcall(complex_match, rb_intern("captures"), 0);
        return rb_funcall(Qnil, rb_intern("Number"), 2, RARRAY_PTR(complex_captures)[0], RARRAY_PTR(complex_captures)[1]);
    }
    else
    {
        VALUE interval_regex = rb_reg_new_str(rb_enc_str_new("^\\[(.*[^\\s]+)\\s*([<≤])\\s*\\((.*[^\\s]+)\\)\\s*([<≤])\\s*(.*[^\\s]+)\\]$", strlen("^\\[(.*[^\\s]+)\\s*([<≤])\\s*\\((.*[^\\s]+)\\)\\s*([<≤])\\s*(.*[^\\s]+)\\]$"), rb_utf8_encoding()), 0);
        VALUE interval_match = rb_funcall(interval_regex, rb_intern("match"), 1, str);
        
        if (RTEST(interval_match))
        {
            VALUE interval_captures = rb_funcall(interval_match, rb_intern("captures"), 0);
            return rb_funcall(Qnil, rb_intern("Number"), 5, RARRAY_PTR(interval_captures)[0], RARRAY_PTR(interval_captures)[2], RARRAY_PTR(interval_captures)[4], *RSTRING_PTR(RARRAY_PTR(interval_captures)[2]) == '<' ? Qtrue : Qfalse, *RSTRING_PTR(RARRAY_PTR(interval_captures)[4]) == '<' ? Qtrue : Qfalse);
        }
        else
        {
            VALUE real_regex = rb_reg_new_str(rb_enc_str_new("^([+-]?[0-9]+):([+-]?[0-9]+)$", strlen("^([+-]?[0-9]+):([+-]?[0-9]+)$"), rb_utf8_encoding()), 0);
            VALUE real_match = rb_funcall(real_regex, rb_intern("match"), 1, str);
            
            if (RTEST(real_match))
            {
                VALUE real_captures = rb_funcall(real_match, rb_intern("captures"), 0);
                VALUE result = rb_obj_alloc(rb_cNumber);
                VALUE integer = rb_funcall(RARRAY_PTR(real_captures)[1], rb_intern("to_i"), 0);
                Real* real = real_from_str((char*)RSTRING_PTR(RARRAY_PTR(real_captures)[0]), NUM2LONG(integer));
                
                DATA_PTR(result) = complex_from_real(real);
                
                return result;
            }
            else if (RSTRING_PTR(str)[0] == -61)
            {
                VALUE result = rb_obj_alloc(rb_cNumber);
                DATA_PTR(result) = complex_nan();
                
                return result;
            }
            else if (RSTRING_PTR(str)[0] == -30)
            {
                VALUE result = rb_obj_alloc(rb_cNumber);
                DATA_PTR(result) = complex_pos_inf();
                
                return result;
            }
            else if ((RSTRING_PTR(str)[0] == 43 || RSTRING_PTR(str)[0] == 45) && RSTRING_PTR(str)[1] == -30)
            {
                VALUE result = rb_obj_alloc(rb_cNumber);
                DATA_PTR(result) = (RSTRING_PTR(str)[0] == 43) ? complex_pos_inf() : complex_neg_inf();
                
                return result;
            }
            else
            {
                VALUE integer_regex = rb_reg_new_str(rb_enc_str_new("^([+-]?[0-9]+)$", strlen("^([+-]?[0-9]+)$"), rb_utf8_encoding()), 0);
                VALUE integer_match = rb_funcall(integer_regex, rb_intern("match"), 1, str);
                
                if (RTEST(integer_match))
                {
                    return rb_funcall(rb_funcall(str, rb_intern("to_i"), 0), rb_intern("to_number"), 0);
                }
                else
                {
                    return rb_funcall(rb_funcall(str, rb_intern("to_f"), 0), rb_intern("to_number"), 0);
                }
            }
        }
    }
    
    /* not reached */
    return Qnil;
}

VALUE rb_Integer_to_number (VALUE integer)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    VALUE str = rb_funcall(integer, rb_intern("to_s"), 0);
    DATA_PTR(result) = complex_from_int_str((char*)RSTRING_PTR(str));
    
    return result;
}

VALUE rb_Float_to_number (VALUE flo)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    VALUE str = rb_funcall(rb_str_new2("%.15e"), rb_intern("%"), 1, flo);
    
    DATA_PTR(result) = complex_from_float_str((char*)RSTRING_PTR(str));
    
    return result;
}

VALUE rb_Complex_to_number (VALUE complex)
{
    Complex* re;
    Complex* im;
    
    re = DATA_PTR(rb_convert_type(rb_funcall(complex, rb_intern("real"), 0), T_DATA, "Number", "to_number"));
    im = DATA_PTR(rb_convert_type(rb_funcall(complex, rb_intern("imag"), 0), T_DATA, "Number", "to_number"));
    
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_new(interval_dup(re->re), interval_dup(im->re));
    
    return result;
}

VALUE rb_f_Number (int argc, VALUE* argv, VALUE obj)
{
    Complex* tmp1;
    Complex* tmp2;
    Complex* tmp3;
    Interval* i1;
    Interval* i2;
    VALUE tmp_A;
    VALUE tmp_B;
    VALUE tmp_C;
    VALUE arg1;
    VALUE arg2;
    VALUE arg3;
    VALUE arg4;
    VALUE arg5;
    VALUE result = rb_obj_alloc(rb_cNumber);
    
    switch (rb_scan_args(argc, argv, "14", &arg1, &arg2, &arg3, &arg4, &arg5))
    {
        case 1:
            tmp_A = rb_convert_type(arg1, T_DATA, "Number", "to_number");
            tmp1 = DATA_PTR(tmp_A);
            
            DATA_PTR(result) = complex_dup(tmp1);
            break;
        
        case 2:
            tmp_A = rb_convert_type(arg1, T_DATA, "Number", "to_number");
            tmp_B = rb_convert_type(arg2, T_DATA, "Number", "to_number");
            
            tmp1 = DATA_PTR(tmp_A);
            tmp2 = DATA_PTR(tmp_B);
            
            Interval* re1 = tmp1->re;
            Interval* re2 = tmp2->re;
            
            i1 = interval_dup(re1);
            i2 = interval_dup(re2);
            
            DATA_PTR(result) = complex_new(i1, i2);
            break;
        
        default:
            tmp_A = rb_convert_type(arg1, T_DATA, "Number", "to_number");
            tmp_B = rb_convert_type(arg2, T_DATA, "Number", "to_number");
            tmp_C = rb_convert_type(arg3, T_DATA, "Number", "to_number");
            
            tmp1 = DATA_PTR(tmp_A);
            tmp2 = DATA_PTR(tmp_B);
            tmp3 = DATA_PTR(tmp_C);
            
            Real* n1 = tmp1->re->n;
            Real* n2 = tmp2->re->n;
            Real* n3 = tmp3->re->n;
            
            Real* r1 = real_dup(n1);
            Real* r2 = real_dup(n2);
            Real* r3 = real_dup(n3);
            
            int L = (argc == 3) ? true : RTEST(arg4);
            int R = (argc == 5) ? RTEST(arg5) : L;
            
            i1 = interval_new(r1, L, r2, R, r3);
            i2 = interval_zero();
            
            DATA_PTR(result) = complex_new(i1, i2);
            break;
    }
    
    return result;
}

VALUE rb_Number_s_allocate (VALUE klass)
{
    return Data_Wrap_Struct(klass, 0, complex_free, 0);
}

VALUE rb_Number_s_digits (VALUE klass)
{
    return LONG2FIX(digs);
}

VALUE rb_Number_s_set_digits (VALUE klass, VALUE n)
{
    digs = FIX2LONG(n);
    return n;
}

VALUE rb_Number_s_nan (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_nan();
    
    return result;
}

VALUE rb_Number_s_pos_inf (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_pos_inf();
    
    return result;
}

VALUE rb_Number_s_neg_inf (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_neg_inf();
    
    return result;
}

VALUE rb_Number_s_zero (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_zero();
    
    return result;
}

VALUE rb_Number_s_one (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_one();
    
    return result;
}

VALUE rb_Number_s_pi (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_pi();
    
    return result;
}

VALUE rb_Number_s_e (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_e();
    
    return result;
}

VALUE rb_Number_s_i (VALUE klass)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_i();
    
    return result;
}

VALUE rb_Number_singleton_method_added (VALUE number, VALUE name)
{
    ID method_id = rb_to_id(name);
    
    rb_remove_method_id(rb_singleton_class(number), method_id);
    rb_raise(rb_eTypeError, "can't define singleton method \"%s\" for %s", rb_id2name(method_id), rb_obj_classname(number));
    
    return Qnil; /* not reached */
}

VALUE rb_Number_initialize_copy (VALUE number, VALUE copy)
{
    rb_raise(rb_eTypeError, "can't copy %s", rb_obj_classname(number));
    return Qnil; /* not reached */
}

VALUE rb_Number_to_c (VALUE number)
{
    VALUE real;
    VALUE imag;
    
    if (complex_re_normal_p(DATA_PTR(number)))
    {
        char re_buf[10000];
        
        complex_print_decimal(re_buf, DATA_PTR(number));
        
        real = DBL2NUM(rb_cstr_to_dbl(re_buf, 0));
    }
    else
    {
        real = complex_re_nan_p(DATA_PTR(number)) ? DBL2NUM(NAN) : complex_re_pos_inf_p(DATA_PTR(number)) ? DBL2NUM(INFINITY) : rb_funcall(DBL2NUM(INFINITY), rb_intern("-@"), 0);
    }
    
    if (complex_im_normal_p(DATA_PTR(number)))
    {
        char im_buf[10000];
        VALUE im = rb_funcall(number, rb_intern("imag"), 0);
        
        complex_print_decimal(im_buf, DATA_PTR(im));
        
        imag = DBL2NUM(rb_cstr_to_dbl(im_buf, 0));
    }
    else
    {
        imag = complex_im_nan_p(DATA_PTR(number)) ? DBL2NUM(NAN) : complex_im_pos_inf_p(DATA_PTR(number)) ? DBL2NUM(INFINITY) : rb_funcall(DBL2NUM(INFINITY), rb_intern("-@"), 0);
    }
    
    return rb_funcall(rb_cObject, rb_intern("Complex"), 2, real, imag);
}

VALUE rb_Number_to_f (VALUE number)
{
    if (complex_re_normal_p(DATA_PTR(number)))
    {
        char buf[10000];
        
        complex_print_decimal(buf, DATA_PTR(number));
        
        return DBL2NUM(rb_cstr_to_dbl(buf, 0));
    }
    else
    {
        return complex_re_nan_p(DATA_PTR(number)) ? DBL2NUM(NAN) : complex_re_pos_inf_p(DATA_PTR(number)) ? DBL2NUM(INFINITY) : rb_funcall(DBL2NUM(INFINITY), rb_intern("-@"), 0);
    }
}

VALUE rb_Number_to_i (VALUE number)
{
    if (complex_re_normal_p(DATA_PTR(number)))
    {
        char buf[10000];
        
        complex_print_int(buf, DATA_PTR(number));
        
        return rb_cstr_to_inum(buf, 10, false);
    }
    else
    {
        return complex_re_nan_p(DATA_PTR(number)) ? DBL2NUM(NAN) : complex_re_pos_inf_p(DATA_PTR(number)) ? DBL2NUM(INFINITY) : rb_funcall(DBL2NUM(INFINITY), rb_intern("-@"), 0);
    }
}

VALUE rb_Number_to_int (VALUE number)
{
    if (complex_re_normal_p(DATA_PTR(number)))
    {
        char buf[10000];
        
        complex_print_int(buf, DATA_PTR(number));
        
        return rb_cstr_to_inum(buf, 10, false);
    }
    else
    {
        return INT2FIX(0);
    }
}

VALUE rb_Number_to_s (VALUE number)
{
    char buf[1000];
    
    complex_print(buf, DATA_PTR(number));
    
    return rb_str_new2(buf);
}

VALUE rb_Number_dummy (VALUE number)
{
    return number;
}

VALUE rb_Number_coerce (VALUE a, VALUE b)
{
    return rb_assoc_new(rb_convert_type(b, T_DATA, "Number", "to_number"), a);
}

VALUE rb_Number_add (VALUE a, VALUE b)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_add(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number")));
    
    return result;
}

VALUE rb_Number_subtract (VALUE a, VALUE b)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_subtract(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number")));
    
    return result;
}

VALUE rb_Number_multiply (VALUE a, VALUE b)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_multiply(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number")));
    
    return result;
}

VALUE rb_Number_divide (VALUE a, VALUE b)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_divide(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number")));
    
    return result;
}

VALUE rb_Number_modulo (VALUE a, VALUE b)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_modulo(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number")));
    
    return result;
}

VALUE rb_Number_eq_p (VALUE a, VALUE b)
{
    return (CLASS_OF(b) == rb_cNumber || rb_obj_is_kind_of(b, rb_cNumeric)) && complex_re_n_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_eqq_p (VALUE a, VALUE b)
{
    return (CLASS_OF(b) == rb_cNumber || rb_obj_is_kind_of(b, rb_cNumeric)) && complex_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_abs (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_abs(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_area (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_area(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_p (VALUE number)
{
    return complex_complex_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_conjugate (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_conjugate(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_diagonal (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_diagonal(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_negate (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_negate(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_p (VALUE number)
{
    return complex_real_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_reflect (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_reflect(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_sqrt (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_sqrt(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_c_c (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_c_c(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_c_f (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_c_f(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_f_c (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_f_c(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_f_f (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_f_f(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_i_i (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_i_i(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_i_o (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_i_o(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_o_i (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_o_i(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_round_o_o (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_round_o_o(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_ll (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_ll(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_lu (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_lu(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_n (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_n(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_ul (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_ul(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_uu (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_uu(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_magnitude (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_magnitude(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_mignitude (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_mignitude(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_complex_width (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_width(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag_l (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im_l(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag_n (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im_n(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag_u (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im_u(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag_magnitude (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im_magnitude(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag_mignitude (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im_mignitude(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_imag_width (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_im_width(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_l (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re_l(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_n (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re_n(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_u (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re_u(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_magnitude (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re_magnitude(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_mignitude (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re_mignitude(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_width (VALUE number)
{
    VALUE result = rb_obj_alloc(rb_cNumber);
    DATA_PTR(result) = complex_re_width(DATA_PTR(number));
    
    return result;
}

VALUE rb_Number_real_intersect_p (VALUE a, VALUE b)
{
    return complex_re_intersect_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_disjoint_p (VALUE a, VALUE b)
{
    return complex_re_disjoint_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_bounded_p (VALUE number)
{
    return complex_re_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_real_left_bounded_p (VALUE number)
{
    return complex_re_left_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_real_right_bounded_p (VALUE number)
{
    return complex_re_right_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_real_unbounded_p (VALUE number)
{
    return complex_re_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_left_unbounded_p (VALUE number)
{
    return complex_re_left_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_right_unbounded_p (VALUE number)
{
    return complex_re_right_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_enclose_p (VALUE a, VALUE b)
{
    return complex_re_enclose_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_contain_l_p (VALUE a, VALUE b)
{
    return complex_re_contain_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_contain_n_p (VALUE a, VALUE b)
{
    return complex_re_contain_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_contain_u_p (VALUE a, VALUE b)
{
    return complex_re_contain_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_contain_zero_p (VALUE number)
{
    return complex_re_contain_zero_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_eq_p (VALUE a, VALUE b)
{
    return complex_re_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_bounds_eq_p (VALUE a, VALUE b)
{
    return complex_re_bounds_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_normal_p (VALUE number)
{
    return complex_re_normal_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_zero_p (VALUE number)
{
    return complex_re_zero_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_nan_p (VALUE number)
{
    return complex_re_nan_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_eq_l_p (VALUE a, VALUE b)
{
    return complex_re_l_eq_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_eq_n_p (VALUE a, VALUE b)
{
    return complex_re_l_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_eq_u_p (VALUE a, VALUE b)
{
    return complex_re_l_eq_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_eq_l_p (VALUE a, VALUE b)
{
    return complex_re_n_eq_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_eq_n_p (VALUE a, VALUE b)
{
    return complex_re_n_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_eq_u_p (VALUE a, VALUE b)
{
    return complex_re_n_eq_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_eq_l_p (VALUE a, VALUE b)
{
    return complex_re_u_eq_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_eq_n_p (VALUE a, VALUE b)
{
    return complex_re_u_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_eq_u_p (VALUE a, VALUE b)
{
    return complex_re_u_eq_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_gt_l_p (VALUE a, VALUE b)
{
    return complex_re_l_gt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_gt_n_p (VALUE a, VALUE b)
{
    return complex_re_l_gt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_gt_u_p (VALUE a, VALUE b)
{
    return complex_re_l_gt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_gt_l_p (VALUE a, VALUE b)
{
    return complex_re_n_gt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_gt_n_p (VALUE a, VALUE b)
{
    return complex_re_n_gt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_gt_u_p (VALUE a, VALUE b)
{
    return complex_re_n_gt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_gt_l_p (VALUE a, VALUE b)
{
    return complex_re_u_gt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_gt_n_p (VALUE a, VALUE b)
{
    return complex_re_u_gt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_gt_u_p (VALUE a, VALUE b)
{
    return complex_re_u_gt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_ge_l_p (VALUE a, VALUE b)
{
    return complex_re_l_ge_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_ge_n_p (VALUE a, VALUE b)
{
    return complex_re_l_ge_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_ge_u_p (VALUE a, VALUE b)
{
    return complex_re_l_ge_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_ge_l_p (VALUE a, VALUE b)
{
    return complex_re_n_ge_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_ge_n_p (VALUE a, VALUE b)
{
    return complex_re_n_ge_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_ge_u_p (VALUE a, VALUE b)
{
    return complex_re_n_ge_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_ge_l_p (VALUE a, VALUE b)
{
    return complex_re_u_ge_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_ge_n_p (VALUE a, VALUE b)
{
    return complex_re_u_ge_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_ge_u_p (VALUE a, VALUE b)
{
    return complex_re_u_ge_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_lt_l_p (VALUE a, VALUE b)
{
    return complex_re_l_lt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_lt_n_p (VALUE a, VALUE b)
{
    return complex_re_l_lt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_lt_u_p (VALUE a, VALUE b)
{
    return complex_re_l_lt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_lt_l_p (VALUE a, VALUE b)
{
    return complex_re_n_lt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_lt_n_p (VALUE a, VALUE b)
{
    return complex_re_n_lt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_lt_u_p (VALUE a, VALUE b)
{
    return complex_re_n_lt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_lt_l_p (VALUE a, VALUE b)
{
    return complex_re_u_lt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_lt_n_p (VALUE a, VALUE b)
{
    return complex_re_u_lt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_lt_u_p (VALUE a, VALUE b)
{
    return complex_re_u_lt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_le_l_p (VALUE a, VALUE b)
{
    return complex_re_l_le_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_le_n_p (VALUE a, VALUE b)
{
    return complex_re_l_le_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_l_le_u_p (VALUE a, VALUE b)
{
    return complex_re_l_le_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_le_l_p (VALUE a, VALUE b)
{
    return complex_re_n_le_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_le_n_p (VALUE a, VALUE b)
{
    return complex_re_n_le_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_n_le_u_p (VALUE a, VALUE b)
{
    return complex_re_n_le_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_le_l_p (VALUE a, VALUE b)
{
    return complex_re_u_le_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_le_n_p (VALUE a, VALUE b)
{
    return complex_re_u_le_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_real_u_le_u_p (VALUE a, VALUE b)
{
    return complex_re_u_le_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_intersect_p (VALUE a, VALUE b)
{
    return complex_im_intersect_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_disjoint_p (VALUE a, VALUE b)
{
    return complex_im_disjoint_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_bounded_p (VALUE number)
{
    return complex_im_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_imag_left_bounded_p (VALUE number)
{
    return complex_im_left_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_imag_right_bounded_p (VALUE number)
{
    return complex_im_right_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_imag_unbounded_p (VALUE number)
{
    return complex_im_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_left_unbounded_p (VALUE number)
{
    return complex_im_left_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_right_unbounded_p (VALUE number)
{
    return complex_im_right_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_enclose_p (VALUE a, VALUE b)
{
    return complex_im_enclose_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_contain_l_p (VALUE a, VALUE b)
{
    return complex_im_contain_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_contain_n_p (VALUE a, VALUE b)
{
    return complex_im_contain_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_contain_u_p (VALUE a, VALUE b)
{
    return complex_im_contain_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_contain_zero_p (VALUE number)
{
    return complex_im_contain_zero_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_eq_p (VALUE a, VALUE b)
{
    return complex_im_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_bounds_eq_p (VALUE a, VALUE b)
{
    return complex_im_bounds_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_nan_p (VALUE number)
{
    return complex_im_nan_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_normal_p (VALUE number)
{
    return complex_im_normal_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_zero_p (VALUE number)
{
    return complex_im_zero_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_eq_l_p (VALUE a, VALUE b)
{
    return complex_im_l_eq_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_eq_n_p (VALUE a, VALUE b)
{
    return complex_im_l_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_eq_u_p (VALUE a, VALUE b)
{
    return complex_im_l_eq_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_eq_l_p (VALUE a, VALUE b)
{
    return complex_im_n_eq_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_eq_n_p (VALUE a, VALUE b)
{
    return complex_im_n_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_eq_u_p (VALUE a, VALUE b)
{
    return complex_im_n_eq_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_eq_l_p (VALUE a, VALUE b)
{
    return complex_im_u_eq_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_eq_n_p (VALUE a, VALUE b)
{
    return complex_im_u_eq_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_eq_u_p (VALUE a, VALUE b)
{
    return complex_im_u_eq_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_gt_l_p (VALUE a, VALUE b)
{
    return complex_im_l_gt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_gt_n_p (VALUE a, VALUE b)
{
    return complex_im_l_gt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_gt_u_p (VALUE a, VALUE b)
{
    return complex_im_l_gt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_gt_l_p (VALUE a, VALUE b)
{
    return complex_im_n_gt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_gt_n_p (VALUE a, VALUE b)
{
    return complex_im_n_gt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_gt_u_p (VALUE a, VALUE b)
{
    return complex_im_n_gt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_gt_l_p (VALUE a, VALUE b)
{
    return complex_im_u_gt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_gt_n_p (VALUE a, VALUE b)
{
    return complex_im_u_gt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_gt_u_p (VALUE a, VALUE b)
{
    return complex_im_u_gt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_ge_l_p (VALUE a, VALUE b)
{
    return complex_im_l_ge_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_ge_n_p (VALUE a, VALUE b)
{
    return complex_im_l_ge_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_ge_u_p (VALUE a, VALUE b)
{
    return complex_im_l_ge_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_ge_l_p (VALUE a, VALUE b)
{
    return complex_im_n_ge_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_ge_n_p (VALUE a, VALUE b)
{
    return complex_im_n_ge_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_ge_u_p (VALUE a, VALUE b)
{
    return complex_im_n_ge_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_ge_l_p (VALUE a, VALUE b)
{
    return complex_im_u_ge_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_ge_n_p (VALUE a, VALUE b)
{
    return complex_im_u_ge_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_ge_u_p (VALUE a, VALUE b)
{
    return complex_im_u_ge_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_lt_l_p (VALUE a, VALUE b)
{
    return complex_im_l_lt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_lt_n_p (VALUE a, VALUE b)
{
    return complex_im_l_lt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_lt_u_p (VALUE a, VALUE b)
{
    return complex_im_l_lt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_lt_l_p (VALUE a, VALUE b)
{
    return complex_im_n_lt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_lt_n_p (VALUE a, VALUE b)
{
    return complex_im_n_lt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_lt_u_p (VALUE a, VALUE b)
{
    return complex_im_n_lt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_lt_l_p (VALUE a, VALUE b)
{
    return complex_im_u_lt_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_lt_n_p (VALUE a, VALUE b)
{
    return complex_im_u_lt_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_lt_u_p (VALUE a, VALUE b)
{
    return complex_im_u_lt_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_le_l_p (VALUE a, VALUE b)
{
    return complex_im_l_le_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_le_n_p (VALUE a, VALUE b)
{
    return complex_im_l_le_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_l_le_u_p (VALUE a, VALUE b)
{
    return complex_im_l_le_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_le_l_p (VALUE a, VALUE b)
{
    return complex_im_n_le_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_le_n_p (VALUE a, VALUE b)
{
    return complex_im_n_le_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_n_le_u_p (VALUE a, VALUE b)
{
    return complex_im_n_le_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_le_l_p (VALUE a, VALUE b)
{
    return complex_im_u_le_l_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_le_n_p (VALUE a, VALUE b)
{
    return complex_im_u_le_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_imag_u_le_u_p (VALUE a, VALUE b)
{
    return complex_im_u_le_u_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_intersect_p (VALUE a, VALUE b)
{
    return complex_intersect_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_disjoint_p (VALUE a, VALUE b)
{
    return complex_disjoint_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_bounded_p (VALUE number)
{
    return complex_unbounded_p(DATA_PTR(number)) ? Qfalse : Qtrue;
}

VALUE rb_Number_complex_unbounded_p (VALUE number)
{
    return complex_unbounded_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_enclose_p (VALUE a, VALUE b)
{
    return complex_enclose_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_contain_ll_p (VALUE a, VALUE b)
{
    return complex_contain_ll_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_contain_lu_p (VALUE a, VALUE b)
{
    return complex_contain_lu_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_contain_n_p (VALUE a, VALUE b)
{
    return complex_contain_n_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_contain_ul_p (VALUE a, VALUE b)
{
    return complex_contain_ul_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_contain_uu_p (VALUE a, VALUE b)
{
    return complex_contain_uu_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_contain_zero_p (VALUE number)
{
    return complex_contain_zero_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_nan_p (VALUE number)
{
    return complex_nan_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_normal_p (VALUE number)
{
    return complex_normal_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_zero_p (VALUE number)
{
    return complex_zero_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_real_p (VALUE number)
{
    return complex_real_p(DATA_PTR(number)) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_eq_p (VALUE a, VALUE b)
{
    return complex_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

VALUE rb_Number_complex_bounds_eq_p (VALUE a, VALUE b)
{
    return complex_bounds_eq_p(DATA_PTR(a), DATA_PTR(rb_convert_type(b, T_DATA, "Number", "to_number"))) ? Qtrue : Qfalse;
}

void Init_number ()
{
    digs = 17;
    
    init_real_tmp_nums();
    init_complex_tmp_nums();
    
    rb_define_method(rb_cNilClass, "to_number", rb_NilClass_to_number, 0);
    rb_define_method(rb_cString, "to_number", rb_String_to_number, 0);
    rb_define_method(rb_cInteger, "to_number", rb_Integer_to_number, 0);
    rb_define_method(rb_cFloat, "to_number", rb_Float_to_number, 0);
    rb_define_method(rb_cComplex, "to_number", rb_Complex_to_number, 0);
    
    rb_cNumber = rb_define_class("Number", rb_cObject);
    rb_undef_method(CLASS_OF(rb_cNumber), "new");
    rb_define_alloc_func(rb_cNumber, rb_Number_s_allocate);
    rb_define_global_function("Number", rb_f_Number, -1);
    
    rb_define_singleton_method(rb_cNumber, "digits", rb_Number_s_digits, 0);
    rb_define_singleton_method(rb_cNumber, "digits=", rb_Number_s_set_digits, 1);
    
    rb_define_singleton_method(rb_cNumber, "nan", rb_Number_s_nan, 0);
    rb_define_singleton_method(rb_cNumber, "pos_inf", rb_Number_s_pos_inf, 0);
    rb_define_singleton_method(rb_cNumber, "neg_inf", rb_Number_s_neg_inf, 0);
    rb_define_singleton_method(rb_cNumber, "zero", rb_Number_s_zero, 0);
    rb_define_singleton_method(rb_cNumber, "one", rb_Number_s_one, 0);
    rb_define_singleton_method(rb_cNumber, "pi", rb_Number_s_pi, 0);
    rb_define_singleton_method(rb_cNumber, "e", rb_Number_s_e, 0);
    rb_define_singleton_method(rb_cNumber, "i", rb_Number_s_i, 0);
    
    rb_define_method(rb_cNumber, "singleton_method_added", rb_Number_singleton_method_added, 1);
    rb_define_method(rb_cNumber, "initialize_copy", rb_Number_initialize_copy, 1);
    
    rb_define_method(rb_cNumber, "to_c", rb_Number_to_c, 0);
    rb_define_method(rb_cNumber, "to_f", rb_Number_to_f, 0);
    rb_define_method(rb_cNumber, "to_i", rb_Number_to_i, 0);
    rb_define_method(rb_cNumber, "to_int", rb_Number_to_int, 0);
    rb_define_method(rb_cNumber, "to_s", rb_Number_to_s, 0);
    rb_define_method(rb_cNumber, "to_number", rb_Number_dummy, 0);
    rb_define_method(rb_cNumber, "coerce", rb_Number_coerce, 1);
    
    rb_define_method(rb_cNumber, "+@", rb_Number_dummy, 0);
    rb_define_method(rb_cNumber, "-@", rb_Number_negate, 0);
    
    rb_define_method(rb_cNumber, "+", rb_Number_add, 1);
    rb_define_method(rb_cNumber, "-", rb_Number_subtract, 1);
    rb_define_method(rb_cNumber, "*", rb_Number_multiply, 1);
    rb_define_method(rb_cNumber, "/", rb_Number_divide, 1);
    rb_define_method(rb_cNumber, "%", rb_Number_modulo, 1);
    
    rb_define_method(rb_cNumber, "==", rb_Number_eq_p, 1);
    rb_define_method(rb_cNumber, "===", rb_Number_eqq_p, 1);
    
    rb_define_method(rb_cNumber, "<", rb_Number_real_n_lt_n_p, 1);
    rb_define_method(rb_cNumber, "<=", rb_Number_real_n_le_n_p, 1);
    rb_define_method(rb_cNumber, ">", rb_Number_real_n_gt_n_p, 1);
    rb_define_method(rb_cNumber, ">=", rb_Number_real_n_ge_n_p, 1);
    
    rb_define_method(rb_cNumber, "abs", rb_Number_abs, 0);
    rb_define_method(rb_cNumber, "area", rb_Number_area, 0);
    rb_define_method(rb_cNumber, "complex?", rb_Number_complex_p, 0);
    rb_define_method(rb_cNumber, "conjugate", rb_Number_conjugate, 0);
    rb_define_method(rb_cNumber, "diagonal", rb_Number_diagonal, 0);
    rb_define_method(rb_cNumber, "imag", rb_Number_imag, 0);
    rb_define_method(rb_cNumber, "negate", rb_Number_negate, 0);
    rb_define_method(rb_cNumber, "real", rb_Number_real, 0);
    rb_define_method(rb_cNumber, "real?", rb_Number_real_p, 0);
    rb_define_method(rb_cNumber, "reflect", rb_Number_reflect, 0);
    rb_define_method(rb_cNumber, "round", rb_Number_round, 0);
    rb_define_method(rb_cNumber, "sqrt", rb_Number_sqrt, 0);
    
    rb_define_method(rb_cNumber, "ceil", rb_Number_round_c_c, 0);
    rb_define_method(rb_cNumber, "floor", rb_Number_round_f_f, 0);
    rb_define_method(rb_cNumber, "round_c_c", rb_Number_round_c_c, 0);
    rb_define_method(rb_cNumber, "round_c_f", rb_Number_round_c_f, 0);
    rb_define_method(rb_cNumber, "round_f_c", rb_Number_round_f_c, 0);
    rb_define_method(rb_cNumber, "round_f_f", rb_Number_round_f_f, 0);
    
    rb_define_method(rb_cNumber, "round_i_i", rb_Number_round_i_i, 0);
    rb_define_method(rb_cNumber, "round_i_o", rb_Number_round_i_o, 0);
    rb_define_method(rb_cNumber, "round_o_i", rb_Number_round_o_i, 0);
    rb_define_method(rb_cNumber, "round_o_o", rb_Number_round_o_o, 0);
    
    rb_define_method(rb_cNumber, "infimum", rb_Number_real_l, 0);
    rb_define_method(rb_cNumber, "l", rb_Number_real_l, 0);
    rb_define_method(rb_cNumber, "real_l", rb_Number_real_l, 0);
    rb_define_method(rb_cNumber, "imag_l", rb_Number_imag_l, 0);
    rb_define_method(rb_cNumber, "complex_ll", rb_Number_complex_ll, 0);
    rb_define_method(rb_cNumber, "complex_lu", rb_Number_complex_lu, 0);
    
    rb_define_method(rb_cNumber, "magnitude", rb_Number_real_magnitude, 0);
    rb_define_method(rb_cNumber, "real_magnitude", rb_Number_real_magnitude, 0);
    rb_define_method(rb_cNumber, "imag_magnitude", rb_Number_imag_magnitude, 0);
    rb_define_method(rb_cNumber, "complex_magnitude", rb_Number_complex_magnitude, 0);
    
    rb_define_method(rb_cNumber, "mignitude", rb_Number_real_mignitude, 0);
    rb_define_method(rb_cNumber, "real_mignitude", rb_Number_real_mignitude, 0);
    rb_define_method(rb_cNumber, "imag_mignitude", rb_Number_imag_mignitude, 0);
    rb_define_method(rb_cNumber, "complex_mignitude", rb_Number_complex_mignitude, 0);
    
    rb_define_method(rb_cNumber, "nominal", rb_Number_real_n, 0);
    rb_define_method(rb_cNumber, "n", rb_Number_real_n, 0);
    rb_define_method(rb_cNumber, "real_n", rb_Number_real_n, 0);
    rb_define_method(rb_cNumber, "imag_n", rb_Number_imag_n, 0);
    rb_define_method(rb_cNumber, "complex_n", rb_Number_complex_n, 0);
    
    rb_define_method(rb_cNumber, "supremum", rb_Number_real_u, 0);
    rb_define_method(rb_cNumber, "u", rb_Number_real_u, 0);
    rb_define_method(rb_cNumber, "real_u", rb_Number_real_u, 0);
    rb_define_method(rb_cNumber, "imag_u", rb_Number_imag_u, 0);
    rb_define_method(rb_cNumber, "complex_ul", rb_Number_complex_uu, 0);
    rb_define_method(rb_cNumber, "complex_uu", rb_Number_complex_ul, 0);
    
    rb_define_method(rb_cNumber, "width", rb_Number_real_width, 0);
    rb_define_method(rb_cNumber, "real_width", rb_Number_real_width, 0);
    rb_define_method(rb_cNumber, "imag_width", rb_Number_imag_width, 0);
    rb_define_method(rb_cNumber, "complex_width", rb_Number_complex_width, 0);
    
    rb_define_method(rb_cNumber, "intersect?", rb_Number_real_intersect_p, 1);
    rb_define_method(rb_cNumber, "real_intersect?", rb_Number_real_intersect_p, 1);
    rb_define_method(rb_cNumber, "imag_intersect?", rb_Number_imag_intersect_p, 1);
    rb_define_method(rb_cNumber, "complex_intersect?", rb_Number_complex_intersect_p, 1);
    
    rb_define_method(rb_cNumber, "disjoint?", rb_Number_real_disjoint_p, 1);
    rb_define_method(rb_cNumber, "real_disjoint?", rb_Number_real_disjoint_p, 1);
    rb_define_method(rb_cNumber, "imag_disjoint?", rb_Number_imag_disjoint_p, 1);
    rb_define_method(rb_cNumber, "complex_disjoint?", rb_Number_complex_disjoint_p, 1);
    
    rb_define_method(rb_cNumber, "enclose?", rb_Number_real_enclose_p, 1);
    rb_define_method(rb_cNumber, "real_enclose?", rb_Number_real_enclose_p, 1);
    rb_define_method(rb_cNumber, "imag_enclose?", rb_Number_imag_enclose_p, 1);
    rb_define_method(rb_cNumber, "complex_enclose?", rb_Number_complex_enclose_p, 1);
    
    rb_define_method(rb_cNumber, "contain_l?", rb_Number_real_contain_l_p, 1);
    rb_define_method(rb_cNumber, "real_contain_l?", rb_Number_real_contain_l_p, 1);
    rb_define_method(rb_cNumber, "imag_contain_l?", rb_Number_imag_contain_l_p, 1);
    rb_define_method(rb_cNumber, "complex_contain_ll?", rb_Number_complex_contain_ll_p, 1);
    rb_define_method(rb_cNumber, "complex_contain_lu?", rb_Number_complex_contain_lu_p, 1);
    
    rb_define_method(rb_cNumber, "contain?", rb_Number_real_contain_n_p, 1);
    rb_define_method(rb_cNumber, "contain_n?", rb_Number_real_contain_n_p, 1);
    rb_define_method(rb_cNumber, "real_contain_n?", rb_Number_real_contain_n_p, 1);
    rb_define_method(rb_cNumber, "imag_contain_n?", rb_Number_imag_contain_n_p, 1);
    rb_define_method(rb_cNumber, "complex_contain_n?", rb_Number_complex_contain_n_p, 1);
    
    rb_define_method(rb_cNumber, "contain_u?", rb_Number_real_contain_u_p, 1);
    rb_define_method(rb_cNumber, "real_contain_u?", rb_Number_real_contain_u_p, 1);
    rb_define_method(rb_cNumber, "imag_contain_u?", rb_Number_imag_contain_u_p, 1);
    rb_define_method(rb_cNumber, "complex_contain_ul?", rb_Number_complex_contain_ul_p, 1);
    rb_define_method(rb_cNumber, "complex_contain_uu?", rb_Number_complex_contain_uu_p, 1);
    
    rb_define_method(rb_cNumber, "contain_zero?", rb_Number_real_contain_zero_p, 0);
    rb_define_method(rb_cNumber, "real_contain_zero?", rb_Number_real_contain_zero_p, 0);
    rb_define_method(rb_cNumber, "imag_contain_zero?", rb_Number_imag_contain_zero_p, 0);
    rb_define_method(rb_cNumber, "complex_contain_zero?", rb_Number_complex_contain_zero_p, 0);
    
    rb_define_method(rb_cNumber, "eq?", rb_Number_real_eq_p, 1);
    rb_define_method(rb_cNumber, "real_eq?", rb_Number_real_eq_p, 1);
    rb_define_method(rb_cNumber, "imag_eq?", rb_Number_imag_eq_p, 1);
    rb_define_method(rb_cNumber, "complex_eq?", rb_Number_complex_eq_p, 1);
    
    rb_define_method(rb_cNumber, "bounds_eq?", rb_Number_real_bounds_eq_p, 1);
    rb_define_method(rb_cNumber, "real_bounds_eq?", rb_Number_real_bounds_eq_p, 1);
    rb_define_method(rb_cNumber, "imag_bounds_eq?", rb_Number_imag_bounds_eq_p, 1);
    rb_define_method(rb_cNumber, "complex_bounds_eq?", rb_Number_complex_bounds_eq_p, 1);
    
    rb_define_method(rb_cNumber, "bounded?", rb_Number_real_bounded_p, 0);
    rb_define_method(rb_cNumber, "real_bounded?", rb_Number_real_bounded_p, 0);
    rb_define_method(rb_cNumber, "imag_bounded?", rb_Number_imag_bounded_p, 0);
    rb_define_method(rb_cNumber, "complex_bounded?", rb_Number_complex_bounded_p, 0);
    
    rb_define_method(rb_cNumber, "unbounded?", rb_Number_real_unbounded_p, 0);
    rb_define_method(rb_cNumber, "real_unbounded?", rb_Number_real_unbounded_p, 0);
    rb_define_method(rb_cNumber, "imag_unbounded?", rb_Number_imag_unbounded_p, 0);
    rb_define_method(rb_cNumber, "complex_unbounded?", rb_Number_complex_unbounded_p, 0);
    
    rb_define_method(rb_cNumber, "left_bounded?", rb_Number_real_left_bounded_p, 0);
    rb_define_method(rb_cNumber, "real_left_bounded?", rb_Number_real_left_bounded_p, 0);
    rb_define_method(rb_cNumber, "imag_left_bounded?", rb_Number_imag_left_bounded_p, 0);
    
    rb_define_method(rb_cNumber, "left_unbounded?", rb_Number_real_left_unbounded_p, 0);
    rb_define_method(rb_cNumber, "real_left_unbounded?", rb_Number_real_left_unbounded_p, 0);
    rb_define_method(rb_cNumber, "imag_left_unbounded?", rb_Number_imag_left_unbounded_p, 0);
    
    rb_define_method(rb_cNumber, "right_bounded?", rb_Number_real_right_bounded_p, 0);
    rb_define_method(rb_cNumber, "real_right_bounded?", rb_Number_real_right_bounded_p, 0);
    rb_define_method(rb_cNumber, "imag_right_bounded?", rb_Number_imag_right_bounded_p, 0);
    
    rb_define_method(rb_cNumber, "right_unbounded?", rb_Number_real_right_unbounded_p, 0);
    rb_define_method(rb_cNumber, "real_right_unbounded?", rb_Number_real_right_unbounded_p, 0);
    rb_define_method(rb_cNumber, "imag_right_unbounded?", rb_Number_imag_right_unbounded_p, 0);
    
    rb_define_method(rb_cNumber, "normal?", rb_Number_real_normal_p, 0);
    rb_define_method(rb_cNumber, "real_normal?", rb_Number_real_normal_p, 0);
    rb_define_method(rb_cNumber, "imag_normal?", rb_Number_imag_normal_p, 0);
    rb_define_method(rb_cNumber, "complex_normal?", rb_Number_complex_normal_p, 0);
    
    rb_define_method(rb_cNumber, "nan?", rb_Number_real_nan_p, 0);
    rb_define_method(rb_cNumber, "real_nan?", rb_Number_real_nan_p, 0);
    rb_define_method(rb_cNumber, "imag_nan?", rb_Number_imag_nan_p, 0);
    rb_define_method(rb_cNumber, "complex_nan?", rb_Number_complex_nan_p, 0);
    
    //rb_define_method(rb_cNumber, "finite?", rb_Number_real_finite_p, 0);
    //rb_define_method(rb_cNumber, "real_finite?", rb_Number_real_finite_p, 0);
    //rb_define_method(rb_cNumber, "imag_finite?", rb_Number_imag_finite_p, 0);
    //rb_define_method(rb_cNumber, "complex_finite?", rb_Number_complex_finite_p, 0);
    //
    //rb_define_method(rb_cNumber, "infinite?", rb_Number_real_infinite_p, 0);
    //rb_define_method(rb_cNumber, "real_infinite?", rb_Number_real_infinite_p, 0);
    //rb_define_method(rb_cNumber, "imag_infinite?", rb_Number_imag_infinite_p, 0);
    //rb_define_method(rb_cNumber, "complex_infinite?", rb_Number_complex_infinite_p, 0);
    
    rb_define_method(rb_cNumber, "zero?", rb_Number_real_zero_p, 0);
    rb_define_method(rb_cNumber, "real_zero?", rb_Number_real_zero_p, 0);
    rb_define_method(rb_cNumber, "imag_zero?", rb_Number_imag_zero_p, 0);
    rb_define_method(rb_cNumber, "complex_zero?", rb_Number_complex_zero_p, 0);
    
    rb_define_method(rb_cNumber, "l_eq_l?", rb_Number_real_l_eq_l_p, 1);
    rb_define_method(rb_cNumber, "real_l_eq_l?", rb_Number_real_l_eq_l_p, 1);
    rb_define_method(rb_cNumber, "imag_l_eq_l?", rb_Number_imag_l_eq_l_p, 1);
    
    rb_define_method(rb_cNumber, "l_eq_n?", rb_Number_real_l_eq_n_p, 1);
    rb_define_method(rb_cNumber, "real_l_eq_n?", rb_Number_real_l_eq_n_p, 1);
    rb_define_method(rb_cNumber, "imag_l_eq_n?", rb_Number_imag_l_eq_n_p, 1);
    
    rb_define_method(rb_cNumber, "l_eq_u?", rb_Number_real_l_eq_u_p, 1);
    rb_define_method(rb_cNumber, "real_l_eq_u?", rb_Number_real_l_eq_u_p, 1);
    rb_define_method(rb_cNumber, "imag_l_eq_u?", rb_Number_imag_l_eq_u_p, 1);
    
    rb_define_method(rb_cNumber, "n_eq_l?", rb_Number_real_n_eq_l_p, 1);
    rb_define_method(rb_cNumber, "real_n_eq_l?", rb_Number_real_n_eq_l_p, 1);
    rb_define_method(rb_cNumber, "imag_n_eq_l?", rb_Number_imag_n_eq_l_p, 1);
    
    rb_define_method(rb_cNumber, "n_eq_n?", rb_Number_real_n_eq_n_p, 1);
    rb_define_method(rb_cNumber, "real_n_eq_n?", rb_Number_real_n_eq_n_p, 1);
    rb_define_method(rb_cNumber, "imag_n_eq_n?", rb_Number_imag_n_eq_n_p, 1);
    
    rb_define_method(rb_cNumber, "n_eq_u?", rb_Number_real_n_eq_u_p, 1);
    rb_define_method(rb_cNumber, "real_n_eq_u?", rb_Number_real_n_eq_u_p, 1);
    rb_define_method(rb_cNumber, "imag_n_eq_u?", rb_Number_imag_n_eq_u_p, 1);
    
    rb_define_method(rb_cNumber, "u_eq_l?", rb_Number_real_u_eq_l_p, 1);
    rb_define_method(rb_cNumber, "real_u_eq_l?", rb_Number_real_u_eq_l_p, 1);
    rb_define_method(rb_cNumber, "imag_u_eq_l?", rb_Number_imag_u_eq_l_p, 1);
    
    rb_define_method(rb_cNumber, "u_eq_n?", rb_Number_real_u_eq_n_p, 1);
    rb_define_method(rb_cNumber, "real_u_eq_n?", rb_Number_real_u_eq_n_p, 1);
    rb_define_method(rb_cNumber, "imag_u_eq_n?", rb_Number_imag_u_eq_n_p, 1);
    
    rb_define_method(rb_cNumber, "u_eq_u?", rb_Number_real_u_eq_u_p, 1);
    rb_define_method(rb_cNumber, "real_u_eq_u?", rb_Number_real_u_eq_u_p, 1);
    rb_define_method(rb_cNumber, "imag_u_eq_u?", rb_Number_imag_u_eq_u_p, 1);
    
    rb_define_method(rb_cNumber, "l_gt_l?", rb_Number_real_l_gt_l_p, 1);
    rb_define_method(rb_cNumber, "real_l_gt_l?", rb_Number_real_l_gt_l_p, 1);
    rb_define_method(rb_cNumber, "imag_l_gt_l?", rb_Number_imag_l_gt_l_p, 1);
    
    rb_define_method(rb_cNumber, "l_gt_n?", rb_Number_real_l_gt_n_p, 1);
    rb_define_method(rb_cNumber, "real_l_gt_n?", rb_Number_real_l_gt_n_p, 1);
    rb_define_method(rb_cNumber, "imag_l_gt_n?", rb_Number_imag_l_gt_n_p, 1);
    
    rb_define_method(rb_cNumber, "l_gt_u?", rb_Number_real_l_gt_u_p, 1);
    rb_define_method(rb_cNumber, "real_l_gt_u?", rb_Number_real_l_gt_u_p, 1);
    rb_define_method(rb_cNumber, "imag_l_gt_u?", rb_Number_imag_l_gt_u_p, 1);
    
    rb_define_method(rb_cNumber, "n_gt_l?", rb_Number_real_n_gt_l_p, 1);
    rb_define_method(rb_cNumber, "real_n_gt_l?", rb_Number_real_n_gt_l_p, 1);
    rb_define_method(rb_cNumber, "imag_n_gt_l?", rb_Number_imag_n_gt_l_p, 1);
    
    rb_define_method(rb_cNumber, "n_gt_n?", rb_Number_real_n_gt_n_p, 1);
    rb_define_method(rb_cNumber, "real_n_gt_n?", rb_Number_real_n_gt_n_p, 1);
    rb_define_method(rb_cNumber, "imag_n_gt_n?", rb_Number_imag_n_gt_n_p, 1);
    
    rb_define_method(rb_cNumber, "n_gt_u?", rb_Number_real_n_gt_u_p, 1);
    rb_define_method(rb_cNumber, "real_n_gt_u?", rb_Number_real_n_gt_u_p, 1);
    rb_define_method(rb_cNumber, "imag_n_gt_u?", rb_Number_imag_n_gt_u_p, 1);
    
    rb_define_method(rb_cNumber, "u_gt_l?", rb_Number_real_u_gt_l_p, 1);
    rb_define_method(rb_cNumber, "real_u_gt_l?", rb_Number_real_u_gt_l_p, 1);
    rb_define_method(rb_cNumber, "imag_u_gt_l?", rb_Number_imag_u_gt_l_p, 1);
    
    rb_define_method(rb_cNumber, "u_gt_n?", rb_Number_real_u_gt_n_p, 1);
    rb_define_method(rb_cNumber, "real_u_gt_n?", rb_Number_real_u_gt_n_p, 1);
    rb_define_method(rb_cNumber, "imag_u_gt_n?", rb_Number_imag_u_gt_n_p, 1);
    
    rb_define_method(rb_cNumber, "u_gt_u?", rb_Number_real_u_gt_u_p, 1);
    rb_define_method(rb_cNumber, "real_u_gt_u?", rb_Number_real_u_gt_u_p, 1);
    rb_define_method(rb_cNumber, "imag_u_gt_u?", rb_Number_imag_u_gt_u_p, 1);
    
    rb_define_method(rb_cNumber, "l_ge_l?", rb_Number_real_l_ge_l_p, 1);
    rb_define_method(rb_cNumber, "real_l_ge_l?", rb_Number_real_l_ge_l_p, 1);
    rb_define_method(rb_cNumber, "imag_l_ge_l?", rb_Number_imag_l_ge_l_p, 1);
    
    rb_define_method(rb_cNumber, "l_ge_n?", rb_Number_real_l_ge_n_p, 1);
    rb_define_method(rb_cNumber, "real_l_ge_n?", rb_Number_real_l_ge_n_p, 1);
    rb_define_method(rb_cNumber, "imag_l_ge_n?", rb_Number_imag_l_ge_n_p, 1);
    
    rb_define_method(rb_cNumber, "l_ge_u?", rb_Number_real_l_ge_u_p, 1);
    rb_define_method(rb_cNumber, "real_l_ge_u?", rb_Number_real_l_ge_u_p, 1);
    rb_define_method(rb_cNumber, "imag_l_ge_u?", rb_Number_imag_l_ge_u_p, 1);
    
    rb_define_method(rb_cNumber, "n_ge_l?", rb_Number_real_n_ge_l_p, 1);
    rb_define_method(rb_cNumber, "real_n_ge_l?", rb_Number_real_n_ge_l_p, 1);
    rb_define_method(rb_cNumber, "imag_n_ge_l?", rb_Number_imag_n_ge_l_p, 1);
    
    rb_define_method(rb_cNumber, "n_ge_n?", rb_Number_real_n_ge_n_p, 1);
    rb_define_method(rb_cNumber, "real_n_ge_n?", rb_Number_real_n_ge_n_p, 1);
    rb_define_method(rb_cNumber, "imag_n_ge_n?", rb_Number_imag_n_ge_n_p, 1);
    
    rb_define_method(rb_cNumber, "n_ge_u?", rb_Number_real_n_ge_u_p, 1);
    rb_define_method(rb_cNumber, "real_n_ge_u?", rb_Number_real_n_ge_u_p, 1);
    rb_define_method(rb_cNumber, "imag_n_ge_u?", rb_Number_imag_n_ge_u_p, 1);
    
    rb_define_method(rb_cNumber, "u_ge_l?", rb_Number_real_u_ge_l_p, 1);
    rb_define_method(rb_cNumber, "real_u_ge_l?", rb_Number_real_u_ge_l_p, 1);
    rb_define_method(rb_cNumber, "imag_u_ge_l?", rb_Number_imag_u_ge_l_p, 1);
    
    rb_define_method(rb_cNumber, "u_ge_n?", rb_Number_real_u_ge_n_p, 1);
    rb_define_method(rb_cNumber, "real_u_ge_n?", rb_Number_real_u_ge_n_p, 1);
    rb_define_method(rb_cNumber, "imag_u_ge_n?", rb_Number_imag_u_ge_n_p, 1);
    
    rb_define_method(rb_cNumber, "u_ge_u?", rb_Number_real_u_ge_u_p, 1);
    rb_define_method(rb_cNumber, "real_u_ge_u?", rb_Number_real_u_ge_u_p, 1);
    rb_define_method(rb_cNumber, "imag_u_ge_u?", rb_Number_imag_u_ge_u_p, 1);
    
    rb_define_method(rb_cNumber, "l_lt_l?", rb_Number_real_l_lt_l_p, 1);
    rb_define_method(rb_cNumber, "real_l_lt_l?", rb_Number_real_l_lt_l_p, 1);
    rb_define_method(rb_cNumber, "imag_l_lt_l?", rb_Number_imag_l_lt_l_p, 1);
    
    rb_define_method(rb_cNumber, "l_lt_n?", rb_Number_real_l_lt_n_p, 1);
    rb_define_method(rb_cNumber, "real_l_lt_n?", rb_Number_real_l_lt_n_p, 1);
    rb_define_method(rb_cNumber, "imag_l_lt_n?", rb_Number_imag_l_lt_n_p, 1);
    
    rb_define_method(rb_cNumber, "l_lt_u?", rb_Number_real_l_lt_u_p, 1);
    rb_define_method(rb_cNumber, "real_l_lt_u?", rb_Number_real_l_lt_u_p, 1);
    rb_define_method(rb_cNumber, "imag_l_lt_u?", rb_Number_imag_l_lt_u_p, 1);
    
    rb_define_method(rb_cNumber, "n_lt_l?", rb_Number_real_n_lt_l_p, 1);
    rb_define_method(rb_cNumber, "real_n_lt_l?", rb_Number_real_n_lt_l_p, 1);
    rb_define_method(rb_cNumber, "imag_n_lt_l?", rb_Number_imag_n_lt_l_p, 1);
    
    rb_define_method(rb_cNumber, "n_lt_n?", rb_Number_real_n_lt_n_p, 1);
    rb_define_method(rb_cNumber, "real_n_lt_n?", rb_Number_real_n_lt_n_p, 1);
    rb_define_method(rb_cNumber, "imag_n_lt_n?", rb_Number_imag_n_lt_n_p, 1);
    
    rb_define_method(rb_cNumber, "n_lt_u?", rb_Number_real_n_lt_u_p, 1);
    rb_define_method(rb_cNumber, "real_n_lt_u?", rb_Number_real_n_lt_u_p, 1);
    rb_define_method(rb_cNumber, "imag_n_lt_u?", rb_Number_imag_n_lt_u_p, 1);
    
    rb_define_method(rb_cNumber, "u_lt_l?", rb_Number_real_u_lt_l_p, 1);
    rb_define_method(rb_cNumber, "real_u_lt_l?", rb_Number_real_u_lt_l_p, 1);
    rb_define_method(rb_cNumber, "imag_u_lt_l?", rb_Number_imag_u_lt_l_p, 1);
    
    rb_define_method(rb_cNumber, "u_lt_n?", rb_Number_real_u_lt_n_p, 1);
    rb_define_method(rb_cNumber, "real_u_lt_n?", rb_Number_real_u_lt_n_p, 1);
    rb_define_method(rb_cNumber, "imag_u_lt_n?", rb_Number_imag_u_lt_n_p, 1);
    
    rb_define_method(rb_cNumber, "u_lt_u?", rb_Number_real_u_lt_u_p, 1);
    rb_define_method(rb_cNumber, "real_u_lt_u?", rb_Number_real_u_lt_u_p, 1);
    rb_define_method(rb_cNumber, "imag_u_lt_u?", rb_Number_imag_u_lt_u_p, 1);
    
    rb_define_method(rb_cNumber, "l_le_l?", rb_Number_real_l_le_l_p, 1);
    rb_define_method(rb_cNumber, "real_l_le_l?", rb_Number_real_l_le_l_p, 1);
    rb_define_method(rb_cNumber, "imag_l_le_l?", rb_Number_imag_l_le_l_p, 1);
    
    rb_define_method(rb_cNumber, "l_le_n?", rb_Number_real_l_le_n_p, 1);
    rb_define_method(rb_cNumber, "real_l_le_n?", rb_Number_real_l_le_n_p, 1);
    rb_define_method(rb_cNumber, "imag_l_le_n?", rb_Number_imag_l_le_n_p, 1);
    
    rb_define_method(rb_cNumber, "l_le_u?", rb_Number_real_l_le_u_p, 1);
    rb_define_method(rb_cNumber, "real_l_le_u?", rb_Number_real_l_le_u_p, 1);
    rb_define_method(rb_cNumber, "imag_l_le_u?", rb_Number_imag_l_le_u_p, 1);
    
    rb_define_method(rb_cNumber, "n_le_l?", rb_Number_real_n_le_l_p, 1);
    rb_define_method(rb_cNumber, "real_n_le_l?", rb_Number_real_n_le_l_p, 1);
    rb_define_method(rb_cNumber, "imag_n_le_l?", rb_Number_imag_n_le_l_p, 1);
    
    rb_define_method(rb_cNumber, "n_le_n?", rb_Number_real_n_le_n_p, 1);
    rb_define_method(rb_cNumber, "real_n_le_n?", rb_Number_real_n_le_n_p, 1);
    rb_define_method(rb_cNumber, "imag_n_le_n?", rb_Number_imag_n_le_n_p, 1);
    
    rb_define_method(rb_cNumber, "n_le_u?", rb_Number_real_n_le_u_p, 1);
    rb_define_method(rb_cNumber, "real_n_le_u?", rb_Number_real_n_le_u_p, 1);
    rb_define_method(rb_cNumber, "imag_n_le_u?", rb_Number_imag_n_le_u_p, 1);
    
    rb_define_method(rb_cNumber, "u_le_l?", rb_Number_real_u_le_l_p, 1);
    rb_define_method(rb_cNumber, "real_u_le_l?", rb_Number_real_u_le_l_p, 1);
    rb_define_method(rb_cNumber, "imag_u_le_l?", rb_Number_imag_u_le_l_p, 1);
    
    rb_define_method(rb_cNumber, "u_le_n?", rb_Number_real_u_le_n_p, 1);
    rb_define_method(rb_cNumber, "real_u_le_n?", rb_Number_real_u_le_n_p, 1);
    rb_define_method(rb_cNumber, "imag_u_le_n?", rb_Number_imag_u_le_n_p, 1);
    
    rb_define_method(rb_cNumber, "u_le_u?", rb_Number_real_u_le_u_p, 1);
    rb_define_method(rb_cNumber, "real_u_le_u?", rb_Number_real_u_le_u_p, 1);
    rb_define_method(rb_cNumber, "imag_u_le_u?", rb_Number_imag_u_le_u_p, 1);
}
